/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package client.ui.fileTransmiting;

import client.ui.fileTransmiting.removingTransmitedFile.RemoveEvent;
import client.ui.fileTransmiting.removingTransmitedFile.RemoveProducer;
import client.ui.fileTransmiting.removingTransmitedFile.RemoveListener;
import java.awt.Dimension;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.BoxLayout;
import javax.swing.JLabel;
import socketHandler.MessageSocketHandler;

/**
 *
 * @author Александр Емельянов (mr.lex91@gmail.com)
 */
public class FileTransmiting extends javax.swing.JFrame {//JDialog {
    
    public class FileTransmitingParams
    {
        public String host;
        public String port;
        public String fileName;
        public String fileRequest;
	public String fileSize;
        
        public FileTransmitingParams(String host, String port, String fileName, String fileRequest, String size)
        {
            this.host = host;
            this.port = port;
            this.fileName = fileName;
            this.fileRequest = fileRequest;
	    this.fileSize=size;
        }
    }
    /**
     * Creates new form FileTransmiting
     */
    public FileTransmiting(java.awt.Frame parent) {
        super("Передача файла");//super(parent, "Передача файла", false);
        initComponents();
        remTransProd=new RemoveProducer();
        remTransProd.setListener(new RemoveListener() {

            @Override
            public synchronized void remove(RemoveEvent evt) {
                HashMap<String, TransmitedFile> hm=transList.get(evt.getNickName());
                TransmitedFile tf=hm.remove(evt.getFileName());
                if (hm.isEmpty())
                {
                    transList.remove(evt.getNickName());
                    if (transList.isEmpty()) stopAcceptionThread();
                }
		removeComp(tf);
            }
        });
	remRecvProd=new RemoveProducer();
	remRecvProd.setListener(new RemoveListener() {

	    @Override
	    public synchronized void remove(RemoveEvent evt) {
		HashMap<String, TransmitedFile> hm=recvList.get(evt.getNickName());
                TransmitedFile tf=hm.remove(evt.getFileName());
                if (hm.isEmpty()) recvList.remove(evt.getNickName());
		removeComp(tf);
	    }
	});
        jPanel1.setLayout(new BoxLayout(jPanel1, BoxLayout.Y_AXIS));
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        jPanel1 = new javax.swing.JPanel();

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        setResizable(false);

        jScrollPane1.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        jScrollPane1.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);

        jPanel1.setAutoscrolls(true);
        jPanel1.setPreferredSize(new java.awt.Dimension(279, 183));

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 279, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 192, Short.MAX_VALUE)
        );

        jScrollPane1.setViewportView(jPanel1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane1)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 194, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents
    public void setHost(String host)
    {
	this.host=host;
    }
    private void startAcceptionThred() throws IOException
    {
	accSoc=new ServerSocket(0, 0, InetAddress.getByName(host));
	port=String.valueOf(accSoc.getLocalPort());
	accThread=new Thread(new Runnable() {

	    @Override
	    public void run() {
		try {
                    while (true)
                    {
                        Socket client=accSoc.accept();
                        Scanner scan=new Scanner(new InputStreamReader(client.getInputStream(),"UTF-8"));
                        String request=scan.nextLine();
                        String nick=request.substring(0,request.indexOf("/"));
                        if (transList.containsKey(nick))
                        {
                            HashMap<String, TransmitedFile> hm=transList.get(nick);
                            String req=request.substring(request.indexOf("/")+1);//,request.length()-1);
                            if (hm.containsKey(req)) hm.get(req).Start(client);
                        }
                    }
		} catch (IOException ex) {}
	    }
	});
	accThread.start();
    }
    private void stopAcceptionThread()
    {
	try {
	    accSoc.close();
	    //accThread.stop();
	} catch (IOException ex) {}
    }
    private synchronized void removeComp(TransmitedFile tf)
    {
	jPanel1.remove(tf);
	Dimension dim=tf.getPreferredSize();
	num--;
	jPanel1.setPreferredSize(new Dimension(dim.width, dim.height*num));
	jScrollPane1.revalidate();
	if (transList.isEmpty() && recvList.isEmpty()) setVisible(false);
    }
    private synchronized void setVis()
    {
        if (transList.isEmpty() && recvList.isEmpty()) setVisible(true);
    }
    public FileTransmitingParams transmit(String userName, File f) throws TransmitedFileIsAlreadyInListException, IOException
    {
	if (transList.isEmpty()) startAcceptionThred();
        setVis();
        if (transList.containsKey(userName))
        {
            HashMap<String, TransmitedFile> hm=transList.get(userName);
            if (!hm.containsKey(f.getAbsolutePath())) addTransm(hm, userName, f);
            else throw new TransmitedFileIsAlreadyInListException();
        }
        else 
        {
            HashMap<String, TransmitedFile> hm=new HashMap<String, TransmitedFile>();
            transList.put(userName, hm);
	    addTransm(hm, userName, f);
        }
        return new FileTransmitingParams(host,port,f.getName(),userName+"/"+f.getAbsolutePath(), String.valueOf(f.length()));
    }
    private void addTransm(HashMap<String, TransmitedFile> hm, String userName, File f)
    {
	TransmitedFile tf=new SendingFille(userName, f, remTransProd, f.length());
	adding(hm, tf, f);
    }
    public synchronized void receive(String userName, String host, String port, File f, String fileRequest, long filesize) throws TransmitedFileIsAlreadyInListException, IOException
    {
	Socket soc=new Socket(host, Integer.valueOf(port));
	if (soc==null) throw new IOException();
        setVis();
        if (recvList.containsKey(userName))
        {
            HashMap<String, TransmitedFile> hm=recvList.get(userName);
            if (!hm.containsKey(f.getAbsolutePath())) addRecive(hm, userName, f,soc, fileRequest, filesize);
            else throw new TransmitedFileIsAlreadyInListException();
        }
        else 
        {
            HashMap<String, TransmitedFile> hm=new HashMap<String, TransmitedFile>();
            recvList.put(userName, hm);
	    addRecive(hm, userName, f,soc, fileRequest, filesize);
        }
    }
    private void addRecive(HashMap<String, TransmitedFile> hm, String userName, File f, Socket soc,String fileRequest, long filesize) throws IOException
    {
	TransmitedFile tf=new ReciveFile(userName, f, remRecvProd, filesize);
	adding(hm, tf, f);
        soc.getOutputStream().write((fileRequest+"\n").getBytes());
	tf.Start(soc);
    }
    private void adding(HashMap<String, TransmitedFile> hm, TransmitedFile tf, File f)
    {
        Dimension dim=tf.getPreferredSize();
        hm.put(f.getAbsolutePath(), tf);
        jPanel1.add(tf);
        num++;
        jPanel1.setPreferredSize(new Dimension(dim.width, dim.height*num));
        jScrollPane1.revalidate();
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    // End of variables declaration//GEN-END:variables
    private HashMap<String, HashMap<String, TransmitedFile>> transList=new HashMap<String, HashMap<String, TransmitedFile>>();
    private HashMap<String, HashMap<String, TransmitedFile>> recvList=new HashMap<String, HashMap<String, TransmitedFile>>();
    private int num=0;
    private RemoveProducer remTransProd;
    private RemoveProducer remRecvProd;
    private String host;
    private String port;
    private ServerSocket accSoc;
    private Thread accThread;
}
